/**
 * 代码评审的列表
 */

import React from 'react';
import PropTypes from 'prop-types';
import { Balloon, Button } from '@teamix/ui';
import { YunxiaoIcon, YunxiaoList } from '@alife/devops-ui';
import UsersAvatar from '@alife/teamix-at-users-avatar';
import { getWebIdeUrl } from 'api';
import utils from 'utils';
import docs from 'utils/docs';
import track from 'utils/track';
import { navigate, Link, navigateOpen, getPathWithNoRootPath } from 'utils/router';
import YundouName from 'components/yundouName';
import DescDivider from 'components/DescDivider';
import Cover from 'atComponents/Cover';
import { getFeature } from 'utils/features';
import BuildsResultTag from '../buildsResultTag';
import './index.scss';
import intl from '../../locale';

const { Tooltip } = Balloon;
const { pathResource } = window.FORCE;

const iconColorMap = {
  opened: 'green',
  reopened: 'green',
  accepted: 'green',
  merged: 'gray',
  closed: 'red',
};

const iconMap = {
  opened: 'pull-request-failed-line',
  reopened: 'pull-request-failed-line',
  accepted: 'pull-request-success-line',
  merged: 'merge-line',
  closed: 'pull-request-closed-line',
};

const textMap = {
  opened: intl.get({
    id: 'code-assets.components.crListItem.EnabledFailedToMeetThe',
    defaultMessage: '已开启·未达到合并要求',
  }),
  reopened: intl.get({
    id: 'code-assets.components.crListItem.EnabledFailedToMeetThe',
    defaultMessage: '已开启·未达到合并要求',
  }),
  accepted: intl.get({
    id: 'code-assets.components.crListItem.EnabledAndCanBeMerged',
    defaultMessage: '已开启·可合并',
  }),
  merged: intl.get({ id: 'code-assets.components.crListItem.Merged', defaultMessage: '已合并' }),
  closed: intl.get({ id: 'code-assets.components.crListItem.Disabled', defaultMessage: '已关闭' }),
};

export default class CodeReviewMedia extends React.Component {
  static propTypes = {
    codeReview: PropTypes.arrayOf(PropTypes.object),
    projectInfo: PropTypes.object,
    projectCloneDownload: PropTypes.object,
  };

  getTag(codeReview) {
    const { state } = codeReview;
    switch (state) {
      case 'opened':
        return (
          <Tooltip trigger={<YunxiaoIcon type="information-line" />} align="t">
            {intl.get({
              id: 'code-assets.components.crListItem.MergeRequirementsNotMet',
              defaultMessage: '未达到合并要求',
            })}
          </Tooltip>
        );

      case 'reopened':
        return (
          <Tooltip trigger={<YunxiaoIcon type="information-line" />} align="t">
            {intl.get({
              id: 'code-assets.components.crListItem.MergeRequirementsNotMet',
              defaultMessage: '未达到合并要求',
            })}
          </Tooltip>
        );

      case 'accepted':
        return (
          <Tooltip trigger={<YunxiaoIcon type="true-line1" />} align="t">
            {intl.get({
              id: 'code-assets.components.crListItem.CanBeMerged',
              defaultMessage: '可合并',
            })}
          </Tooltip>
        );

      default:
        return '';
    }
  }

  /**
   * Process code review source and target
   * Now, it may be branch or commit
   *
   * If it is commit(SHA), will process it
   *
   * @param {string} content
   * @param {string} type
   */
  getCRContentByType(content, type) {
    if (type === 'COMMIT') {
      return utils.showShortSha(content);
    } else {
      return content;
    }
  }

  goWebIde = (codeReview) => {
    const { pageType } = this.props;
    if (pageType) {
      track({
        action: 'goto_webide',
        page: pageType,
        type: '',
        control: '',
      });
    }
    getWebIdeUrl(
      {
        filepath: '',
        branch: codeReview.source_branch,
        commit: '',
        line: '',
        column: '',
        type: 'mergerequest',
        merge_commit: codeReview.target_branch,
        mergerequestId: codeReview.id,
      },
      codeReview.project_id,
    )
      .then((result) => {
        navigateOpen(result.endpoint);
      })
      .catch((err) => {
        console.error(err);
      });
  };

  render() {
    const { codeReview, projectInfo, projectCloneDownload, ipSetting } = this.props;
    if (!codeReview) {
      return false;
    }

    codeReview.assignees.forEach((item) => {
      if (item.avatar_url) item.avatarUrl = item.avatar_url;
      switch (item.status) {
        case 'approved':
          item.statusText = intl.get({
            id: 'code-assets.components.crListItem.Passed',
            defaultMessage: '已通过',
          });
          item.marker = (
            <div className="mr-overview-avatar-marker commented">
              <img src="https://img.alicdn.com/tfs/TB1.4QPii_1gK0jSZFqXXcpaXXa-24-24.png" alt="" />
            </div>
          );

          break;
        case 'comment':
          item.statusText = intl.get({
            id: 'code-assets.components.crListItem.Commented',
            defaultMessage: '已评论',
          });
          item.marker = (
            <div className="mr-overview-avatar-marker reviewed">
              <img src="https://img.alicdn.com/tfs/TB1THZNieL2gK0jSZPhXXahvXXa-24-24.png" alt="" />
            </div>
          );

          break;
        case 'pending':
          item.statusText = intl.get({
            id: 'code-assets.components.crListItem.Failed',
            defaultMessage: '未通过',
          });
          item.marker = (
            <div className="mr-overview-avatar-marker not-reviewed">
              <img src="https://img.alicdn.com/tfs/TB1kVgRihv1gK0jSZFFXXb0sXXa-24-24.png" alt="" />
            </div>
          );

          break;
        default:
          item.statusText = '';
          item.marker = null;
      }
    });

    let repoDescription;
    let repoPath;

    if (codeReview.repoPath) {
      repoPath = `/${codeReview.repoPath}`;
      repoDescription = (
        <span className="media-secondary-info-item">
          <a href={repoPath} target="_blank" rel="noreferrer">
            {codeReview.repoPath}
          </a>
        </span>
      );
    } else if (
      !(pathResource && pathResource.id) ||
      (pathResource && pathResource.type === 'GROUP')
    ) {
      // 如果是dashboard或者group下的代码评审，使用web_url属性来构造链接
      const { pathname } = new URL(codeReview.web_url);
      repoPath = getPathWithNoRootPath(pathname);

      repoDescription = (
        <Tooltip
          trigger={
            <span className="media-secondary-info-item">
              <span href={`${pathname}`} className="cr-list-item-repo" target="_blank">
                {utils.getGroupPath(codeReview.name_with_namespace)}
              </span>
            </span>
          }
        >
          {intl.get({
            id: 'code-assets.components.crListItem.CodeBase',
            defaultMessage: '代码库：',
          })}

          {utils.getGroupPath(codeReview.name_with_namespace)}
        </Tooltip>
      );
    } else {
      repoPath = `/${pathResource.fullPath}`;
    }

    const jumpUrl = `${repoPath}/merge_request/${codeReview.id}`;
    const time_doc =
      codeReview.attributes &&
      codeReview.attributes.length &&
      codeReview.attributes[0].attributeType === 'merge_request_time'
        ? JSON.parse(codeReview.attributes[0].attributeInfo).time_doc
        : '';
    const is_auto_create =
      codeReview.is_auto_create === true || codeReview.is_auto_create === 'true';
    const createTime = utils.getBeautyTime(codeReview.created_at, window.FORCE.locale, 'simple');

    const description = [
      repoDescription || null,
      repoDescription ? <DescDivider /> : null,
      <Tooltip
        trigger={
          <span className="cr-list-item-branch-container">
            <span
              href={`${repoPath}/tree/${utils.revisionEncodeURI(codeReview.source_branch)}`}
              className="cr-list-item-branch"
              target="_blank"
            >
              {this.getCRContentByType(codeReview.source_branch, codeReview.source_type)}
            </span>{' '}
            <YunxiaoIcon type="arrow-right-line" size="small" className="cr-list-icon" />{' '}
            <span
              href={`${repoPath}/tree/${utils.revisionEncodeURI(codeReview.target_branch)}`}
              className="cr-list-item-branch"
              target="_blank"
            >
              {this.getCRContentByType(codeReview.target_branch, codeReview.target_type)}
            </span>
          </span>
        }
        closable={false}
      >
        <span>
          {intl.get({ id: 'code-assets.components.crListItem.From', defaultMessage: '从' })}{' '}
          {this.getCRContentByType(codeReview.source_branch, codeReview.source_type)}{' '}
          {intl.get({ id: 'code-assets.components.crListItem.Merge', defaultMessage: '合并到' })}{' '}
          {this.getCRContentByType(codeReview.target_branch, codeReview.target_type)}
        </span>
      </Tooltip>,
      <DescDivider />,
      <span
        title={
          is_auto_create
            ? intl.get(
                {
                  id: 'code-assets.components.crListItem.TheCloudBeanBotWas',
                  defaultMessage: '云豆 bot 创建于 {createTime}',
                },
                { createTime },
              )
            : intl.get(
                {
                  id: 'code-assets.components.crListItem.CodereviewauthornameWasCreatedInCreatetime',
                  defaultMessage: '{codeReviewAuthorName} 创建于 {createTime}',
                },
                { codeReviewAuthorName: codeReview.author.name, createTime },
              )
        }
      >
        <a>{is_auto_create ? <YundouName /> : codeReview.author.name}</a>
        <span>
          {' '}
          {intl.get({
            id: 'code-assets.components.crListItem.CreatedOn',
            defaultMessage: '创建于',
          })}{' '}
          {createTime}
        </span>
      </span>,
    ];
    let timeTxt = null;
    if (time_doc) {
      if (time_doc === 'unsupported') {
        timeTxt = (
          <Balloon
            closable={false}
            trigger={
              <span>
                {intl.get({
                  id: 'code-assets.components.crListItem.NoEstimate',
                  defaultMessage: '暂无预估',
                })}
              </span>
            }
            align="t"
          >
            {intl.get({
              id: 'code-assets.components.crListItem.CurrentlyTheFileTypeCannot',
              defaultMessage: '文件类型暂不支持预估，查看',
            })}

            <a
              href={docs('estimatedReviewTime')}
              target="_blank"
              style={{ color: '#488ee2' }}
              rel="noreferrer"
            >
              {intl.get({
                id: 'code-assets.components.crListItem.ServiceDescription',
                defaultMessage: '服务说明',
              })}
            </a>
          </Balloon>
        );
      } else if (time_doc.startsWith('>')) {
        const time = time_doc.slice(1);
        timeTxt = (
          <Balloon.Tooltip
            trigger={
              <span>
                {intl.get(
                  {
                    id: 'code-assets.components.crListItem.MoreThanTimeMinutes',
                    defaultMessage: '大于 {time} 分钟',
                  },
                  { time },
                )}
              </span>
            }
            align="t"
          >
            {intl.get(
              {
                id: 'code-assets.components.crListItem.TheEstimatedReviewTimeIs',
                defaultMessage: '预估评审耗时大于 {time} 分钟',
              },
              { time },
            )}
          </Balloon.Tooltip>
        );
      } else {
        timeTxt = (
          <Balloon.Tooltip
            trigger={
              <span>
                {intl.get(
                  {
                    id: 'code-assets.components.crListItem.AboutTimedocMinutes',
                    defaultMessage: '约 {timeDoc} 分钟',
                  },
                  { timeDoc: time_doc },
                )}
              </span>
            }
            align="t"
          >
            {intl.get(
              {
                id: 'code-assets.components.crListItem.EstimatedReviewTimeAboutTimedoc',
                defaultMessage: '预估评审耗时约 {timeDoc} 分钟',
              },
              { timeDoc: time_doc },
            )}
          </Balloon.Tooltip>
        );
      }
    }

    const dataSource = {
      left: (
        <Tooltip
          trigger={
            <Cover
              type="icon"
              icon={
                <YunxiaoIcon
                  type={iconMap[codeReview.state]}
                  style={{ color: `${iconColorMap[codeReview.state]}` }}
                />
              }
            />
          }
          align="t"
        >
          {textMap[codeReview.state]}
        </Tooltip>
      ),

      body: {
        title: [<span className="cr-title">{codeReview.title}</span>],
        description: [
          ...description,
          time_doc ? (
            <>
              <DescDivider />
              <span onClick={(e) => e.stopPropagation()}>
                <YunxiaoIcon type="clock-line" /> {timeTxt}
              </span>
            </>
          ) : null,
        ],
      },

      right: {
        items: [
          codeReview.assignees ? (
            <span
              className="cr-list-item-assignees"
              onClick={() => {
                // TODO containerProps 右侧不可点的bug
                navigate(jumpUrl);
              }}
            >
              <UsersAvatar dataSource={codeReview.assignees} />
            </span>
          ) : null,
          <span
            onClick={(e) => {
              e.preventDefault();
              e.stopPropagation();
            }}
          >
            <BuildsResultTag
              container={{
                target: 'merge_request', // 可选值为 commit 和 merge_request
                id: codeReview.id, // commit 或 merge_request 的 id
                projectId: codeReview.project_id,
              }}
              projectInfo={projectInfo}
            />
          </span>,
        ],
        timeItems: [
          <span
            onClick={() => {
              navigate(jumpUrl);
            }}
          >
            {intl.get({
              id: 'code-assets.components.crListItem.UpdatedOn',
              defaultMessage: '更新于',
            })}{' '}
            {utils.getBeautyTime(codeReview.updated_at, window.FORCE.locale, 'simple')}
          </span>,
        ],
      },
      containerProps: {
        to: `${repoPath}/merge_request/${codeReview.id}`,
        onClick: () => {
          track({
            action: 'open_mr',
            page: 'Repo-MR-changes',
            type: '',
            control: '',
            mr_id: codeReview.id,
            user_id: window.FORCE.user ? window.FORCE.user.codeUserId : '',
            tb_user_id: window.FORCE.user ? window.FORCE.user.id : '',
          });
        },
      },
    };

    if (getFeature('WebIDE.entrance.mr')) {
      dataSource.right.timeItems.push(
        <>
          {
            // eslint-disable-next-line no-nested-ternary
            ipSetting && ipSetting.ip_whitelist_enabled && ipSetting.scope === 'all' ? (
              <Balloon.Tooltip
                align="l"
                trigger={
                  <Button
                    disabled
                    onClick={(e) => {
                      e.stopPropagation();
                      this.goWebIde(codeReview);
                    }}
                  >
                    WebIDE
                  </Button>
                }
              >
                {intl.get({
                  id: 'code-assets.components.mergeRequsetInfo.TheEnterpriseHasEnabledIp',
                  defaultMessage: '企业已启用 IP 白名单严格管控，暂不支持使用 WebIDE',
                })}
              </Balloon.Tooltip>
            ) : projectCloneDownload?.httpCloneLimit?.state === 'disable' &&
              projectCloneDownload?.sshCloneLimit?.state === 'disable' ? (
                <Balloon.Tooltip
                  align="l"
                  trigger={
                    <Button
                      disabled
                      onClick={(e) => {
                        e.preventDefault();
                        e.stopPropagation();
                        this.goWebIde(codeReview);
                      }}
                    >
                      WebIDE
                    </Button>
                  }
                >
                  已启用仓库克隆下载控制，暂不支持使用 WebIDE，请联系管理员处理
                </Balloon.Tooltip>
            ) : (
              <Balloon.Tooltip
                align="t"
                trigger={
                  <Button
                    onClick={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      this.goWebIde(codeReview);
                    }}
                  >
                    WebIDE
                  </Button>
                }
              >
                {intl.get({
                  id: 'code-assets.components.crListItem.WeipingOnlineReview',
                  defaultMessage: 'WebIDE 在线评审',
                })}
              </Balloon.Tooltip>
            )
          }
        </>,
      );
    }

    return (
      <Link to={dataSource.containerProps.to}>
        <YunxiaoList.Item
          style={{ cursor: 'pointer' }}
          title={dataSource.body.title}
          description={dataSource.body.description}
          cover={dataSource.left}
          onClick={() => {}}
          extra={
            <>
              <YunxiaoList.Item.Actions width="144px" align="left">
                {dataSource.right.items[1]}
              </YunxiaoList.Item.Actions>
              <YunxiaoList.Item.Actions width="140px" align="right">
                {dataSource.right.items[0]}
              </YunxiaoList.Item.Actions>
              {dataSource.right.timeItems.length === 1 ? (
                <YunxiaoList.Item.Actions
                  width="160px"
                  align="right"
                >
                  {dataSource.right.timeItems[0]}
                </YunxiaoList.Item.Actions>
              ) : (
                <YunxiaoList.Item.HoverToggles
                  width="160px"
                  align="right"
                >
                  {dataSource.right.timeItems[0]}
                  {dataSource.right.timeItems[1]}
                </YunxiaoList.Item.HoverToggles>
              )}
            </>
          }
        />
      </Link>
    );
  }
}
